package org.jsola.hr.service.impl;

import com.alibaba.fastjson.JSONObject;
import org.jsola.core.Page;
import org.jsola.exception.ParamException;
import org.jsola.hr.common.ExampleKit;
import org.jsola.hr.common.ExcelKit;
import org.jsola.hr.constant.HrConstants;
import org.jsola.hr.dao.IMissionCenterItemDAO;
import org.jsola.hr.dto.MissionCenterFeedBackDTO;
import org.jsola.hr.dto.MissionCenterItemAddDTO;
import org.jsola.hr.dto.MissionCenterItemUpdateDTO;
import org.jsola.hr.entity.MissionCenterDO;
import org.jsola.hr.entity.MissionCenterItemDO;
import org.jsola.hr.exception.HrException;
import org.jsola.hr.provider.IUserProviderService;
import org.jsola.hr.query.MissionCenterItemQuery;
import org.jsola.hr.service.IMissionCenterItemService;
import org.jsola.hr.service.IMissionCenterService;
import org.jsola.hr.service.IMissionItemFeedbackService;
import org.jsola.hr.vo.MissionCenterItemListVO;
import org.jsola.hr.vo.MissionCenterItemVO;
import org.jsola.user.core.TokenUser;
import org.jsola.user.entity.UserDO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
import tk.mybatis.mapper.entity.Example;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 任务调度中心任务子项表
 *
 * @author zhr
 */
@Service("hrMissionCenterItemServiceImpl")
public class MissionCenterItemServiceImpl implements IMissionCenterItemService {

    @Autowired
    private IMissionCenterItemDAO missionCenterItemDAO;

    @Autowired
    private IUserProviderService userProviderService;

    @Autowired
    private IMissionCenterService missionCenterService;

    @Autowired
    private IMissionItemFeedbackService missionItemFeedbackService;

    private static final Integer MAX_REMARK = 255;

    @Override
    @Transactional(value = HrConstants.TX, rollbackFor = Exception.class)
    public MissionCenterItemVO save(MissionCenterItemAddDTO missionCenterItemAddDTO, TokenUser tokenUser) {
        // 转DO
        MissionCenterItemDO missionCenterItemDO = missionCenterItemAddDTO.to(MissionCenterItemDO.class);
        // 保存
        missionCenterItemDO = save(missionCenterItemDO, tokenUser.getSiteId(), tokenUser.getUserId());
        return missionCenterItemDO.to(MissionCenterItemVO.class);
    }

    @Override
    @Transactional(value = HrConstants.TX, rollbackFor = Exception.class)
    public int update(MissionCenterItemUpdateDTO missionCenterItemUpdateDTO, TokenUser tokenUser) {
        //转DO
        MissionCenterItemDO missionCenterItemDO = missionCenterItemUpdateDTO.to(MissionCenterItemDO.class);
        //根据主键更新，只更新非null值
        return updateByIdSelective(missionCenterItemDO, tokenUser.getSiteId(), tokenUser.getUserId());
    }

    @Override
    @Transactional(value = HrConstants.TX, rollbackFor = Exception.class)
    public int deleteByIds(TokenUser tokenUser, String... missionCenterItemIds) {
        return logicalDeleteByIds(tokenUser.getSiteId(), tokenUser.getUserId(), (Object[]) missionCenterItemIds);
    }


    @Override
    public MissionCenterItemVO selectById(String missionCenterItemId, String siteId) {
        MissionCenterItemDO missionCenterItemDO = selectDOById(missionCenterItemId, siteId);
        if (missionCenterItemDO == null) {
            return null;
        }
        return missionCenterItemDO.to(MissionCenterItemVO.class);
    }

    @Override
    public List<MissionCenterItemListVO> select(MissionCenterItemQuery missionCenterItemQuery, String siteId) {
        List<MissionCenterItemDO> missionCenterItemDOList = selectDO(missionCenterItemQuery, siteId);
        if (CollectionUtils.isEmpty(missionCenterItemDOList)) {
            return missionCenterItemDOList == null ? null : new ArrayList<>();
        }
        return missionCenterItemDOList.stream()
                .map(missionCenterItemDO -> missionCenterItemDO.to(MissionCenterItemListVO.class))
                .collect(Collectors.toList());
    }

    @Override
    public int selectCount(MissionCenterItemQuery missionCenterItemQuery, String siteId) {
        Example example = buildExample(missionCenterItemQuery, siteId);
        return missionCenterItemDAO.selectCountByExample(example);
    }

    @Override
    public Page<MissionCenterItemListVO> selectPage(MissionCenterItemQuery missionCenterItemQuery, String siteId) {
        Example example = buildExample(missionCenterItemQuery, siteId);
        Page<MissionCenterItemDO> page = missionCenterItemDAO.selectPageByExample(example,
                missionCenterItemQuery.getPageNo(),
                missionCenterItemQuery.getPageSize());

        return page.to(MissionCenterItemListVO.class);
    }

    @Override
    public MissionCenterItemDO selectDOById(String missionCenterItemId, String siteId) {
        return listById(missionCenterItemId, siteId);
    }

    @Override
    public List<MissionCenterItemDO> selectDO(MissionCenterItemQuery missionCenterItemQuery, String siteId) {
        Example example = buildExample(missionCenterItemQuery, siteId);
        return missionCenterItemDAO.selectByExample(example);
    }

    @Override
    public List<MissionCenterItemDO> selectByMissionCenterId(String missionCenterId, String siteId) {
        Example example = new Example(MissionCenterItemDO.class);
        example.and()
                .andEqualTo("valid", true)
                .andEqualTo("missionCenterId", missionCenterId)
                .andEqualTo("siteId", siteId);
        return missionCenterItemDAO.selectByExample(example);
    }

    @Override
    public List<MissionCenterItemDO> selectByMissionCenterIdList(List<String> missionCenterIdList, String siteId) {
        Example example = new Example(MissionCenterItemDO.class);
        example.and()
                .andEqualTo("valid", true)
                .andIn("missionCenterId", missionCenterIdList)
                .andEqualTo("siteId", siteId);
        return missionCenterItemDAO.selectByExample(example);
    }

    @Override
    public Page<MissionCenterItemListVO> selectMissionCenterItem(MissionCenterItemQuery missionCenterItemQuery, String siteId) {
        Example example = buildExampleByQuery(missionCenterItemQuery, siteId);
        Page<MissionCenterItemDO> page = missionCenterItemDAO.selectPageByExample(example,
                missionCenterItemQuery.getPageNo(), missionCenterItemQuery.getPageSize());
        Page<MissionCenterItemListVO> resultPage = page.to(MissionCenterItemListVO.class);
        List<MissionCenterItemListVO> resultList = resultPage.getEntities();
        for (MissionCenterItemListVO missionCenterItemListVO : resultList) {
            String feedbackUser = missionCenterItemListVO.getFeedbackUser();
            if (!StringUtils.isEmpty(feedbackUser)) {
                UserDO userDO = userProviderService.selectUserById(feedbackUser);
                if(!ObjectUtils.isEmpty(userDO)){
                    missionCenterItemListVO.setFeedbackUser(userDO.getName());
                }
            }
        }
        resultPage.setEntities(resultList);
        return resultPage;
    }

    @Override
    @Transactional(value = HrConstants.TX, rollbackFor = Exception.class)
    public Integer feedback(MissionCenterFeedBackDTO missionCenterFeedBackDTO, TokenUser tokenUser) {
        Example example = new Example(MissionCenterItemDO.class);
        example.and()
                .andEqualTo("valid", true)
                .andEqualTo("siteId", tokenUser.getSiteId())
                .andIn("id", missionCenterFeedBackDTO.getItemIdList());
        MissionCenterItemDO missionCenterItemDO = new MissionCenterItemDO();
        missionCenterItemDO.setState(missionCenterFeedBackDTO.getState());
        if (!StringUtils.isEmpty(missionCenterFeedBackDTO.getRemark())) {
            if (missionCenterFeedBackDTO.getRemark().length() > MAX_REMARK) {
                throw new ParamException("反馈内容不得超过255个字符");
            }
            missionCenterItemDO.setRemark(missionCenterFeedBackDTO.getRemark());
        }
        missionCenterItemDO.setFeedbackDate(new Date());
        missionCenterItemDO.setFeedbackUser(tokenUser.getUserId());
        int feedbackResult = missionCenterItemDAO.updateByExampleSelective(missionCenterItemDO, example);
        if (feedbackResult == 0) {
            throw new HrException("更新失败");
        }
        missionItemFeedbackService.batchSaveFeedback(missionCenterFeedBackDTO, tokenUser);
        return feedbackResult;
    }

    @Override
    public String exportReceivePath(MissionCenterItemQuery missionCenterItemQuery, TokenUser tokenUser) {
        ParamException.notNull(missionCenterItemQuery.getMissionCenterId(), "请选择导出派单表");
        MissionCenterDO missionCenterDO = missionCenterService.
                selectDOById(missionCenterItemQuery.getMissionCenterId(), tokenUser.getSiteId());
        String tableHeadStr = missionCenterDO.getTableHead();
        String[] tableHeadList = tableHeadStr.split(",");
        // 表头容器定义
        List<List<String>> headList = new ArrayList<>();
        // 所有的数据容器定义
        List<List<String>> dataList = new ArrayList<>();
        for (String head : tableHeadList) {
            List<String> oneHead = new ArrayList<>();
            oneHead.add(head);
            headList.add(oneHead);
        }
        List<String> stateHead = new ArrayList<>();
        stateHead.add("状态");
        List<String> feedbackHead = new ArrayList<>();
        feedbackHead.add("最后反馈内容");
        headList.add(feedbackHead);
        headList.add(stateHead);
        List<MissionCenterItemDO> itemList = selectAllMissionCenterItem(missionCenterItemQuery, tokenUser.getSiteId());
        for (MissionCenterItemDO missionCenterItem : itemList) {
            List<String> oneData = new ArrayList<>();
            String headDataJson = missionCenterItem.getTableData();
            Map<String, Object> dataMap = JSONObject.parseObject(headDataJson);
            for (String head : tableHeadList) {
                String data = (String) dataMap.get(head);
                oneData.add(data);
            }
            oneData.add(missionCenterItem.getRemark());
            oneData.add(conversionState(missionCenterItem.getState()));
            dataList.add(oneData);
        }
        return ExcelKit.exportExcelDynamic("emptyMissionCenterReceive", "接单列表", dataList, headList);
    }

    /**
     * 根据参数全量查询子项列表
     */
    private List<MissionCenterItemDO> selectAllMissionCenterItem(MissionCenterItemQuery missionCenterItemQuery, String siteId) {
        Example example = buildExampleByQuery(missionCenterItemQuery, siteId);
        return missionCenterItemDAO.selectByExample(example);
    }

    /**
     * 构建example根据查询参数
     */
    private Example buildExampleByQuery(MissionCenterItemQuery missionCenterItemQuery, String siteId) {
        Example example = new Example(MissionCenterItemDO.class);
        example.and()
                .andEqualTo("valid", true)
                .andEqualTo("missionCenterId", missionCenterItemQuery.getMissionCenterId())
                .andEqualTo("siteId", siteId);
        if (!ObjectUtils.isEmpty(missionCenterItemQuery.getState())) {
            example.and().andEqualTo("state", missionCenterItemQuery.getState());
        }
        if (!CollectionUtils.isEmpty(missionCenterItemQuery.getItemIdList())) {
            example.and().andIn("id", missionCenterItemQuery.getItemIdList());
        }
        if (!ObjectUtils.isEmpty(missionCenterItemQuery.getKeyWord())) {
            example.and().andLike("tableData", "%" + missionCenterItemQuery.getKeyWord() + "%");
        }
        return example;
    }

    /**
     * 转换state
     */
    private String conversionState(Integer state) {
        switch (state) {
            case 0:
                return "未完成";
            case 1:
                return "已完成";
            case 2:
                return "异常";
            default:
                throw new IllegalStateException("Unexpected value: " + state);
        }
    }

    /**
     * 根据查询参数，构建example
     *
     * @param missionCenterItemQuery 查询参数
     * @param siteId                 所属站点id
     * @return example
     */
    private Example buildExample(MissionCenterItemQuery missionCenterItemQuery, String siteId) {
        Example example = new Example(MissionCenterItemDO.class);
        example.and()
                .andEqualTo("valid", true)
                .andEqualTo("siteId", siteId);
        // 排序
        ExampleKit.setExampleOrder(example, missionCenterItemQuery.getOrders());
        return example;
    }
}




